package com.caseprocessing.api;

import com.caseprocessing.config.AIConfig;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadLocalRandom;

/**
 * SiliconFlow API客户端
 * 集成LLM和VLM能力的统一API接口
 */
public class SiliconFlowClient {
    
    private final String apiKey;
    private final String baseUrl;
    private final HttpClient httpClient;
    private final ObjectMapper objectMapper;
    private final RetryConfig retryConfig;
    private final AIConfig config;
    
    // 动态模型配置
    private final String llmModel;
    private final String vlmModel;
    
    public SiliconFlowClient(String apiKey) {
        this.config = AIConfig.getInstance();
        this.apiKey = apiKey != null ? apiKey : config.getApiKey();
        this.baseUrl = config.getApiBaseUrl().replace("/chat/completions", "");
        this.llmModel = config.getLlmModelName();
        this.vlmModel = config.getVlmModelName();
        
        this.httpClient = HttpClient.newBuilder()
                .connectTimeout(Duration.ofMillis(config.getApiTimeout()))
                .build();
        this.objectMapper = new ObjectMapper();
        this.retryConfig = new RetryConfig();
        
        // 验证配置
        if (this.apiKey == null || "your_api_key_here".equals(this.apiKey)) {
            System.err.println("⚠️ API密钥未配置，请设置有效的API密钥");
        }
        
        if (config.isApiLogsEnabled()) {
            System.out.println("🔗 SiliconFlow客户端初始化完成");
            System.out.println("  基础URL: " + this.baseUrl);
            System.out.println("  LLM模型: " + this.llmModel);
            System.out.println("  VLM模型: " + this.vlmModel);
        }
    }
    
    /**
     * 使用配置文件中的API密钥创建客户端
     */
    public SiliconFlowClient() {
        this(null);
    }
    
    /**
     * LLM聊天补全 - 用于语义理解和推理
     */
    public CompletableFuture<ChatCompletionResponse> chatCompletionLLM(
            List<Message> messages, 
            ChatCompletionRequest.Builder requestBuilder) {
        
        ChatCompletionRequest request = requestBuilder
                .model(llmModel)
                .messages(messages)
                .maxTokens(config.getLlmMaxTokens())
                .temperature(config.getLlmTemperature())
                .topP(config.getLlmTopP())
                .build();
                
        return executeWithRetry(() -> sendChatCompletion(request));
    }
    
    /**
     * VLM多模态理解 - 用于图像+文本分析
     */
    public CompletableFuture<ChatCompletionResponse> chatCompletionVLM(
            List<Message> messages,
            List<String> imageUrls,
            ChatCompletionRequest.Builder requestBuilder) {
        
        // 构建包含图像的消息
        List<Message> vlmMessages = buildVLMMessages(messages, imageUrls);
        
        ChatCompletionRequest request = requestBuilder
                .model(vlmModel)
                .messages(vlmMessages)
                .maxTokens(config.getVlmMaxTokens())
                .temperature(config.getVlmTemperature())
                .topP(config.getVlmTopP())
                .build();
                
        return executeWithRetry(() -> sendChatCompletion(request));
    }
    
    /**
     * 发送聊天补全请求
     */
    private CompletableFuture<ChatCompletionResponse> sendChatCompletion(ChatCompletionRequest request) {
        try {
            String requestBody = objectMapper.writeValueAsString(request);
            
            HttpRequest httpRequest = HttpRequest.newBuilder()
                    .uri(URI.create(baseUrl + "/chat/completions"))
                    .header("Authorization", "Bearer " + apiKey)
                    .header("Content-Type", "application/json")
                    .POST(HttpRequest.BodyPublishers.ofString(requestBody))
                    .build();
            
            return httpClient.sendAsync(httpRequest, HttpResponse.BodyHandlers.ofString())
                    .thenApply(this::parseResponse);
                    
        } catch (Exception e) {
            CompletableFuture<ChatCompletionResponse> future = new CompletableFuture<>();
            future.completeExceptionally(e);
            return future;
        }
    }
    
    /**
     * 解析API响应
     */
    private ChatCompletionResponse parseResponse(HttpResponse<String> response) {
        try {
            if (response.statusCode() == 200) {
                return objectMapper.readValue(response.body(), ChatCompletionResponse.class);
            } else {
                throw new SiliconFlowApiException("API调用失败: " + response.statusCode() + " - " + response.body());
            }
        } catch (Exception e) {
            throw new RuntimeException("响应解析失败", e);
        }
    }
    
    /**
     * 构建VLM消息（包含图像）
     */
    private List<Message> buildVLMMessages(List<Message> textMessages, List<String> imageUrls) {
        List<Message> vlmMessages = new ArrayList<>(textMessages);
        
        if (imageUrls != null && !imageUrls.isEmpty()) {
            for (String imageUrl : imageUrls) {
                Message imageMessage = Message.builder()
                        .role("user")
                        .content(List.of(
                                new ContentPart("image_url", Map.of("url", imageUrl))
                        ))
                        .build();
                vlmMessages.add(imageMessage);
            }
        }
        
        return vlmMessages;
    }
    
    /**
     * 带重试的执行
     */
    private <T> CompletableFuture<T> executeWithRetry(java.util.function.Supplier<CompletableFuture<T>> operation) {
        return operation.get()
                .exceptionallyCompose(throwable -> {
                    if (shouldRetry(throwable) && retryConfig.shouldRetry()) {
                        // 指数退避延迟
                        int delay = retryConfig.getNextDelay();
                        System.out.println("API调用失败，" + delay + "ms后重试...");
                        
                        return CompletableFuture.delayedExecutor(
                                Duration.ofMillis(delay),
                                java.util.concurrent.ForkJoinPool.commonPool()
                        ).execute(() -> executeWithRetry(operation));
                    } else {
                        CompletableFuture<T> future = new CompletableFuture<>();
                        future.completeExceptionally(throwable);
                        return future;
                    }
                });
    }
    
    /**
     * 判断是否应该重试
     */
    private boolean shouldRetry(Throwable throwable) {
        if (throwable instanceof SiliconFlowApiException) {
            SiliconFlowApiException apiException = (SiliconFlowApiException) throwable;
            // 429 (Rate Limit), 500, 502, 503, 504 应该重试
            return apiException.getStatusCode() == 429 || 
                   (apiException.getStatusCode() >= 500 && apiException.getStatusCode() <= 504);
        }
        // 网络异常也应该重试
        return throwable instanceof java.net.ConnectException || 
               throwable instanceof java.net.SocketTimeoutException;
    }
    
    /**
     * 文档分析专用方法
     */
    public CompletableFuture<DocumentAnalysisResult> analyzeDocument(
            String documentText, 
            List<String> documentImages, 
            String analysisType) {
        
        String prompt = buildDocumentAnalysisPrompt(analysisType);
        
        List<Message> messages = List.of(
                Message.builder()
                        .role("system")
                        .content(prompt)
                        .build(),
                Message.builder()
                        .role("user")
                        .content("请分析以下文档内容：\n" + documentText)
                        .build()
        );
        
        // 如果有图像，使用VLM；否则使用LLM
        CompletableFuture<ChatCompletionResponse> responseFuture;
        if (documentImages != null && !documentImages.isEmpty()) {
            responseFuture = chatCompletionVLM(messages, documentImages, 
                    ChatCompletionRequest.builder().temperature(0.1));
        } else {
            responseFuture = chatCompletionLLM(messages, 
                    ChatCompletionRequest.builder().temperature(0.1));
        }
        
        return responseFuture.thenApply(this::parseDocumentAnalysisResult);
    }
    
    /**
     * 构建文档分析提示词
     */
    private String buildDocumentAnalysisPrompt(String analysisType) {
        switch (analysisType) {
            case "structure_analysis":
                return """
                你是一个专业的法律文书分析专家。请分析文档的结构特征：
                1. 识别文档类型（封面、目录、处罚决定书、调查笔录等）
                2. 提取关键信息区域（标题、文号、日期、签名、印章位置）
                3. 评估文档完整性和质量
                4. 返回JSON格式的结构化分析结果
                """;
                
            case "content_classification":
                return """
                你是一个法律文书分类专家。请对文档内容进行精确分类：
                1. 判断文书的具体类型和子类型
                2. 分析文书在执法流程中的位置
                3. 提取关键业务要素
                4. 给出分类置信度和判断依据
                """;
                
            case "compliance_check":
                return """
                你是一个行政执法合规专家。请检查文书的合规性：
                1. 对照相关法律法规检查程序合规性
                2. 验证必要要素的完整性
                3. 检查逻辑一致性和格式规范性
                4. 提供具体的问题描述和改进建议
                """;
                
            default:
                return "请对文档进行综合分析，提取关键信息并给出专业建议。";
        }
    }
    
    /**
     * 解析文档分析结果
     */
    private DocumentAnalysisResult parseDocumentAnalysisResult(ChatCompletionResponse response) {
        try {
            String content = response.getChoices().get(0).getMessage().getContent();
            
            // 尝试解析JSON格式的结构化结果
            if (content.trim().startsWith("{")) {
                return objectMapper.readValue(content, DocumentAnalysisResult.class);
            } else {
                // 如果不是JSON，创建包含文本内容的结果
                return DocumentAnalysisResult.builder()
                        .rawContent(content)
                        .confidence(0.8)
                        .build();
            }
        } catch (Exception e) {
            throw new RuntimeException("文档分析结果解析失败", e);
        }
    }
    
    /**
     * 重试配置
     */
    private static class RetryConfig {
        private int currentAttempt = 0;
        private final int maxRetries = 3;
        private final int baseDelay = 1000; // 1秒
        
        public boolean shouldRetry() {
            return currentAttempt < maxRetries;
        }
        
        public int getNextDelay() {
            currentAttempt++;
            // 指数退避 + 随机抖动
            int delay = baseDelay * (1 << (currentAttempt - 1));
            int jitter = ThreadLocalRandom.current().nextInt(0, delay / 2);
            return delay + jitter;
        }
    }
    
    /**
     * SiliconFlow API异常
     */
    public static class SiliconFlowApiException extends RuntimeException {
        private final int statusCode;
        
        public SiliconFlowApiException(String message) {
            super(message);
            this.statusCode = -1;
        }
        
        public SiliconFlowApiException(int statusCode, String message) {
            super(message);
            this.statusCode = statusCode;
        }
        
        public int getStatusCode() {
            return statusCode;
        }
    }
}